//! 消息传递并发示例
//!
//! 展示如何使用通道在线程间传递消息
//!
//! ## 概念说明
//!
//! 一个日益流行的确保安全并发的方式是消息传递（message passing），
//! 线程（或actor）之间通过发送包含数据的消息来相互沟通。
//! 这个概念的一个重要指导原则是：
//!
//! > 不要共享状态来通信，而要通过通信来共享状态（Do not communicate by sharing memory; instead, share memory by communicating.）
//!
//! Go语言文档中也提到了这一理念。Rust标准库提供了用于消息传递的通道（channel）实现。
//!
//! ## 通道（Channel）
//!
//! 通道是通用的编程概念，Rust的通道实现遵循标准的模式：
//! - 创建一个发送者（transmitter）和一个接收者（receiver）
//! - 发送者用于发送数据
//! - 接收者用于接收数据
//! - 发送者和接收者被称为"通道的两端"
//!
//! ## 消息传递相关知识点
//!
//! | 知识点 | 说明 |
//! |--------|------|
//! | mpsc::channel | 创建多生产者单消费者通道 |
//! | Sender | 发送数据的一端 |
//! | Receiver | 接收数据的一端 |
//! | send方法 | 发送数据，返回Result<T, E> |
//! | recv方法 | 接收数据，阻塞当前线程 |
//! | try_recv方法 | 非阻塞接收数据 |
//! | 多生产者 | 可以通过clone方法创建多个发送者 |

use std::sync::mpsc;
use std::thread;
use std::time::Duration;

/// 使用通道在多个线程间传递消息
///
/// 创建一个通道并在线程间传递消息。
/// `mpsc`是"multiple producer, single consumer"的缩写。
pub fn channel_example() {
    // 创建一个新的通道，返回发送者和接收者
    let (tx, rx) = mpsc::channel();

    // 在新线程中发送数据
    thread::spawn(move || {
        let vals = vec![String::from("hi"), String::from("from"), String::from("the"), String::from("thread")];

        for val in vals {
            tx.send(val).unwrap();
            thread::sleep(Duration::from_secs(1));
        }
    });

    // 在主线程中接收数据
    for received in rx {
        println!("Got: {}", received);
    }
}

/// 多生产者示例
///
/// 展示如何创建多个发送者来向同一个接收者发送消息。
/// 通过克隆发送者，可以创建多个生产者。
pub fn multiple_producers() {
    let (tx, rx) = mpsc::channel();
    // 克隆发送者以创建多个生产者
    let tx1 = tx.clone();

    thread::spawn(move || {
        let vals = vec![String::from("hi"), String::from("from"), String::from("the"), String::from("first"), String::from("thread")];

        for val in vals {
            tx1.send(val).unwrap();
            thread::sleep(Duration::from_secs(1));
        }
    });

    thread::spawn(move || {
        let vals = vec![String::from("more"), String::from("messages"), String::from("for"), String::from("you")];

        for val in vals {
            tx.send(val).unwrap();
            thread::sleep(Duration::from_secs(1));
        }
    });

    for received in rx.try_iter() {
        println!("Received: {}", received);
    }

    // 等待一段时间以确保所有消息都被处理
    thread::sleep(Duration::from_secs(5));

    for received in rx.try_iter() {
        println!("Received: {}", received);
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_channel() {
        // 这个测试不会验证输出，只是确保代码能正常运行
        channel_example();
    }

    #[test]
    fn test_multiple_producers() {
        multiple_producers();
    }
}
